<template>
    <div>
        <div v-if="mode !== 'edit'" class="v-modal" tabindex="0" style="z-index: 3016;"></div>
        <div
            class="tips"
            :style="tipsPosStyle"
            v-if="app && mode === 'study' && showTips && app.tips !== undefined"
            v-html="app.tips"
        />
        <div ref="appItemRef"
            v-if="mode !== 'edit'"
            tabindex="0"
            class="app"
            :style="appPosStyle"
            @keyup.enter.stop.prevent="itemEvent('keyup.enter')"
            @keyup.ctrl.13="itemEvent('keyup.ctrl.13')"
        >
            <h3 class="title">{{ item.title }}</h3>
            <el-button type="info" icon="el-icon-minus" circle @click="itemClose"/>
            <div
                class="element"
                v-for="item in app.items"
                v-if="item.display !== false"
                :key="item.name"
                :style="itemStyle(item)"
            >
                <div
                    v-if="item.type === 'zone'"
                    style="width: 100%; height: 100%"
                    v-bind="item.props"
                    @click="itemClick(item)"
                />
                <div
                    v-if="item.type === 'label'"
                    style="width: 100%; height: 100%"
                    v-bind="item.props"
                    v-html="item.content"
                    @click="itemClick(item)"
                />
                <img
                    v-if="item.type === 'image'"
                    :src="'/api' + item.icon"
                    v-bind="item.props"
                    @click="itemClick(item)"
                >
                <input
                    type="text"
                    v-if="item.type === 'input'"
                    v-model="item.value"
                    v-bind="item.props"
                    @keyup.enter.stop.prevent="itemChange(item)"
                >
                <select
                    v-if="item.type === 'select'"
                    v-model="item.value"
                    v-bind="item.props"
                    @change="itemChange(item)"
                >
                    <option v-for="opt in item.content.split(',')" :key="opt" :value="opt">{{opt}}</option>
                </select>
            </div>
        </div>
        <div v-if="mode === 'edit'" class="app edit" :style="appPosStyle">
            <VueDragResize
                class="element"
                v-for="item in app.items"
                v-if="item.display !== false"
                :key="item.name"
                @activated="activateEv(item)"
                :w="item.w"
                :h="item.h"
                :x="item.x"
                :y="item.y"
                :isActive="activedItem && activedItem.name === item.name"
                :parentW="counter.appWindowArea.w"
                :parentH="counter.appWindowArea.h"
                :minw="10"
                :minh="10"
                :isDraggable="true"
                :isResizable="true"
                :parentLimitation="true"
                v-on:dragging="changePosition"
                v-on:resizing="changeSize"
            >
                <div
                    v-if="item.type === 'zone'"
                    style="width: 100%; height: 100%"
                    v-bind="item.props"
                />
                <div
                    v-if="item.type === 'label'"
                    style="width: 100%; height: 100%"
                    v-bind="item.props"
                    v-html="item.content"
                />
                <img v-if="item.type === 'image'" :src="'/api' + item.icon" v-bind="item.props">
                <input
                    type="text"
                    v-if="item.type === 'input'"
                    v-model="item.value"
                    v-bind="item.props"
                >
                <select v-if="item.type === 'select'" v-model="item.value" v-bind="item.props">
                    <option v-for="opt in item.content.split(',')" :key="opt" :value="opt ? opt.trim(): ''">{{opt}}</option>
                </select>
            </VueDragResize>
        </div>
    </div>
</template>
<script>
import VueDragResize from 'vue-drag-resize'
import Vue from 'vue'
import { eventMap } from '../data/consts'

export default {
    name: 'app-item',
    data() {
        return {
            showTips: true
        }
    },
    props: ['item', 'apps', 'counter', 'mode'],
    components: { VueDragResize },
    computed: {
        activedItem() {
            return this.$store.state.course.activedItem
        },
        app: function() {
            return this.apps.find(app => app.name === this.item.content)
        },
        appPosStyle: function() {
            const { x, y, w, h } = this.counter.appWindowArea
            return {
                position: this.mode === 'edit' ? 'relative' : 'absolute',
                top: this.mode === 'edit' ? 0 : y + 'px',
                left: this.mode === 'edit' ? 0 : x + 'px',
                width: w + 'px',
                height: h + 'px',
                backgroundImage: this.app && this.app.background ? `url(/api${this.app.background})` : ''
            }
        },
        tipsPosStyle: function() {
            const { x, y, w, h } = this.counter.appTipsArea
            return {
                top: y + 'px',
                left: x + 'px',
                width: w + 'px',
                height: h + 'px'
            }
        }
    },
    mounted() {
        if(this.$refs.appItemRef) {
            this.$refs.appItemRef.focus();
        }
        console.log("update focus")
    },
    methods: {
        itemEvent(binding) {
            if (this.app.events && this.app.events[binding]) {
                this.execute(this.app.events, binding)
            }
        },
        execute(item, event, expect, result) {
            console.log('app >> execute >> ', item)
            const { show, hide, pages, app, score } = item[event]
            const keepApp = this.app

            if ((this.mode === 'study' && expect == result) || this.mode === 'exam') {
                this.pagesChange(item, event, pages)
                this.itemShow(show)
                this.itemHide(hide)
                this.appChange(app)
            }

            if (score) {
                this.$emit('addResults', {
                    name: `${keepApp.name}-${item.name}`,
                    event: eventMap[event],
                    expect,
                    result,
                    score: expect == result ? score : 0
                })
            }
        },
        pagesChange(item, event, pages) {
            if (pages) {
                this.$emit('change', item, event, pages)
            }
        },
        itemCheck(item) {
            const { check } = item.onClick
            if (check) {
                let result = true
                const checks = check.split(',')
                this.app.items.forEach(item => {
                    checks.forEach(v => {
                        if (item.name === v) {
                            result = result && item.onChange !== undefined && item.onChange.value == item.value
                        }
                    })
                })
                this.execute(item, 'onClick', true, result)
            }
        },
        itemShow(show) {
            if (show) {
                const shows = show.split(',')
                this.app.items.forEach(item => {
                    shows.forEach(v => {
                        if (item.name === v) {
                            item.display = true
                        }
                    })
                })
            }
        },
        itemHide(hide) {
            if (hide) {
                const hides = hide.split(',')
                this.app.items.forEach(item => {
                    hides.forEach(v => {
                        if (v === 'self') {
                            this.item.display = false
                            this.$emit('itemChange', this.item)
                        }
                        if (item.name === v) {
                            item.display = false
                        }
                    })
                })
            }
        },
        appChange(app) {
            if (app) {
                this.item.content = app
                this.$emit('itemChange', this.item)
            }
        },
        itemStyle(item) {
            return {
                position: 'absolute',
                top: item.y + 'px',
                left: item.x + 'px',
                width: item.w + 'px',
                height: item.h + 'px'
            }
        },
        itemClick(item) {
            if (item.onClick) {
                if (item.onClick.check) {
                    this.itemCheck(item)
                } else {
                    this.execute(item, 'onClick')
                }
            }
        },
        itemChange(item) {
            if (item.onChange) {
                const { value, pages, show, hide } = item.onChange
                const finalValue = item.lastValue ? `${item.lastValue},${item.value}` : item.value
                this.execute(item, 'onChange', value, finalValue)
            }
        },
        itemClose() {
            this.item.display = false
            this.$emit('itemChange', this.item)
        },
        activateEv(item) {
            if (this.mode === 'edit') {
                this.$store.commit('course/update', { activedItem: item })
                this.$store.commit('course/update', { activedConfig: 'item' })
            }
        },

        deactivateEv(index) {},

        changePosition(rect) {
            const { top, left } = rect
            Vue.set(this.activedItem, 'x', left)
            Vue.set(this.activedItem, 'y', top)
            this.$store.commit('course/updateActivedItem', this.activedItem)
        },

        changeSize(rect) {
            const { width, height } = rect
            Vue.set(this.activedItem, 'w', width)
            Vue.set(this.activedItem, 'h', height)
            this.$store.commit('course/updateActivedItem', this.activedItem)
        }
    }
}
</script>
<style lang="less">
.tips {
    z-index: 4000;
    position: absolute;
    border-radius: 5px;
    background-color: #fff;
    border: 15px solid #ccc;
}
.app {
    z-index: 4000;
    border-radius: 5px;
    background-color: #fff;
    background-repeat: round;
    background-size: contain;
    border: 15px solid #333;
    &.edit {
        z-index: auto;
        border: none;
    }
    .title {
        color: #eee;
        position: absolute;
        left: -35px;
        top: -45px;
    }
    .el-button.el-button--small.is-circle {
        position: absolute;
        right: -30px;
        top: -30px;
    }
    .element {
        img {
            width: 100%;
            height: 100%;
        }
        input {
            width: 100%;
            height: 100%;
        }
        select {
            width: 100%;
            height: 100%;
        }
    }
}
</style>


